home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 17 / CU Amiga Magazine's Super CD-ROM 17 (1997)(EMAP Images)(GB)[!][issue 1997-12].iso / CUCD / Programming / DiceSource / src / dcpp / save / xxx < prev   
Text File  |  1993-01-20  |  9KB  |  487 lines

  1.  
  2. /*
  3.  *  CPP.C
  4.  *
  5.  * (c)Copyright 1992 Obvious Implementations Corp, All Rights Reserved
  6.  * CONFIDENTIAL, This is unpublished proprietary source code owned by Obvious Implementations Corp.
  7.  * This material contains trade secrets of Obvious Implementations Corp.
  8.  *
  9.  */
  10.  
  11. #include "defs.h"
  12.  
  13. Prototype Include *PushBase;
  14. Prototype char WhiteSpace[256];
  15. Prototype char SpecialChar[256];
  16. Prototype char SymbolChar[256];
  17.  
  18. Prototype void InitCpp(void);
  19. Prototype long cpp(long, int, char *, FILE *, char *, long);
  20. Prototype long SkipCommentLine(ubyte *, long, long);
  21. Prototype long SkipComment(ubyte *, long, long);
  22. Prototype long ExtSymbol(ubyte *, long, long);
  23. Prototype long SkipString(char *, long, long);
  24. Prototype long SkipSingleSpec(char *, long, long);
  25. Prototype void Dump(char *, long, long);
  26. Prototype void DoLineSpec(void);
  27.  
  28. Include *PushBase;
  29. char WhiteSpace[256];
  30. char SpecialChar[256];
  31. char SymbolChar[256];
  32.  
  33. void
  34. InitCpp()
  35. {
  36.     short i;
  37.  
  38.     WhiteSpace[9] = 1;
  39.     WhiteSpace[' '] = 1;
  40.     WhiteSpace['\r'] = 1;
  41.     WhiteSpace['l'&31] = 1;
  42.  
  43.     for (i = '0'; i <= '9'; ++i)
  44.     SymbolChar[i] = 1;
  45.     for (i = 'a'; i <= 'z'; ++i)
  46.     SymbolChar[i] = 1;
  47.     for (i = 'A'; i <= 'Z'; ++i)
  48.     SymbolChar[i] = 1;
  49.     SymbolChar['_'] = 1;
  50.     SymbolChar[1] = 1;        /*    special for macro replace */
  51.  
  52.     SpecialChar['\''] = 1;
  53.     SpecialChar['\"'] = 1;
  54.     SpecialChar['/'] = 1;
  55.     SpecialChar['?'] = 1;
  56. }
  57.  
  58. long
  59. cpp(oldi, level, file, fi, xbuf, xbytes)
  60. long oldi;
  61. int level;
  62. char *file;
  63. FILE *fi;
  64. char *xbuf;
  65. long xbytes;
  66. {
  67.     long len;
  68.     long i;
  69.     long w;
  70.     short ifIndex = IfIndex;
  71.     ubyte *base;
  72.     Include inc;
  73.  
  74.     if (level >= MAX_INCLUDE_LEVEL)
  75.     cerror(EFATAL_MAX_INCLUDE, level);
  76.  
  77.     if (fi == NULL && xbuf == NULL) {
  78.     ErrorOpenFailed(file, 0);
  79.     return(oldi);
  80.     }
  81.     if (fi) {
  82.     fprintf(Fo, "# 1 \"%s\" %d\n", file, level);
  83.     fseek(fi, 0L, 2);
  84.     len = ftell(fi);
  85.     if (len < 0) {
  86.         cerror(EERROR_FILE_SIZE, file, len);
  87.         fclose(fi);
  88.         return(oldi);
  89.     }
  90.     base = malloc(len+1);
  91.     if (base == NULL)
  92.         ErrorNoMemory();
  93.     fseek(fi, 0L, 0);
  94.     { 
  95.         int n;
  96.  
  97.         if ((n = fread(base, 1, len, fi)) != len) {
  98.         cerror(EERROR_READ_ERROR, file);
  99.         fclose(fi);
  100.         return(oldi);
  101.         }
  102.     }
  103.     fclose(fi);     /*  fi no longer valid */
  104.  
  105.     base[len] = 0;     /*  emergency terminator to prevent bad code from crashing us!  */
  106.  
  107.     /*
  108.      *  Check for tri-graphs, modify accordingly
  109.      */
  110.  
  111.     if (TriGraph) {
  112. #ifdef NO_ASM
  113.         char *ptr = base;
  114.         char c;
  115.  
  116.         while (c = *ptr) {
  117.         ++ptr;
  118.         if (c == '?' && *ptr == '?') {
  119.             if (c = TriGraphConvert(ptr[1])) {
  120.             ptr[-1] = c;
  121.             len -= 2;
  122.             movmem(ptr + 2, ptr, len - (ptr - (char *)base));
  123.             }
  124.         }
  125.         }
  126. #else
  127.         len = HandleTriGraphs(base) - base;
  128. #endif
  129.     }
  130.     } else {         /*  else macro  */
  131.     base = xbuf;
  132.     len = xbytes;
  133.     }
  134.     dbprintf(("CPP %s (%ld)\n", file, len));
  135.  
  136.     if (PushBase)
  137.     PushBase->Index = oldi;
  138.  
  139.     inc.Next = PushBase;
  140.     inc.FileName = file;
  141.     inc.LineNo     = 1;
  142.     inc.Level     = level;
  143.     inc.IsFile     = (fi) ? 1 : 0;
  144.     inc.MaxIndex = len;
  145.     inc.Base     = base;
  146.     PushBase = &inc;
  147.  
  148.     {
  149.     int nl = 1;                /*    newline just occured */
  150.     short c;
  151.     short stringtize = 0;
  152.  
  153.     for (i = w = 0; i < len; ) {
  154.         c = base[i];
  155.  
  156.         if (WhiteSpace[c]) {        /*    ignore white space   */
  157.         ++i;
  158.         continue;
  159.         }
  160.         if (c == '\n') {                /*  newline              */
  161.         /*
  162.          *  handle line concat.  XXX handle escape sequences? ANSI?
  163.          */
  164.         if (w < i && base[i-1] == '\\') {
  165.             Dump(base, w, i - 1);
  166.             w = i + 1;
  167.             ForceLineSpec = 1;
  168.         } else {
  169.             if (ForceLineSpec) {
  170.             Dump(base, w, i);
  171.             w = i;
  172.             DoLineSpec();
  173.             }
  174.         }
  175.         ++inc.LineNo;
  176.         nl = 1;
  177.         ++i;
  178.         continue;
  179.         }
  180.         if (c == '#') {                 /*  directive, token pasting  */
  181.         if (nl && fi) {
  182.             dbprintf(("directive\n"));
  183.             Dump(base, w, i);
  184.                             /*    execute directive    */
  185.             w = i = HandleDirective(base, i + 1, len);
  186.             continue;
  187.         } else if (base[i+1] == '#') {
  188.             long si = i + 2;
  189.             while (i >= w && WhiteSpace[base[--i]]);
  190.             ++i;
  191.             Dump(base, w, i);
  192.             i = si;
  193.             while (i < len && WhiteSpace[base[i]])
  194.             ++i;
  195.             w = i;
  196.             continue;
  197.         } else if (fi == NULL) {
  198.             Dump(base, w, i);
  199.             stringtize = 1;
  200.             w = ++i;
  201.             continue;
  202.         }
  203.         }
  204.         nl = 0;                /*    NOT a directive      */
  205.  
  206.         /*
  207.          *    Do not misinterpret a number as a symbol, especially parts
  208.          *    of the number that contain characters such as 0x23 or
  209.          *    0.234E+4  It will suffice to include '.' in our definition
  210.          *    of a symbol for this loop
  211.          *
  212.          *    Note that embedded characters in numbers will not be handled
  213.          *    by DC1 if symbolized for precompiled includes, but the
  214.          *    processing of this is handled in PRECOMP.C, not here.
  215.          */
  216.  
  217.         if (c >= '0' && c <= '9') {
  218.         for (++i; i < len && (SymbolChar[c = base[i]] || c == '.'); ++i)
  219.             ;
  220.         continue;
  221.         }
  222.  
  223.         /*
  224.          *    symbol?
  225.          */
  226.  
  227.         if (IfEnabled && SymbolChar[c]) {
  228.         long b = i;
  229.         Sym *node;
  230.  
  231.         i = ExtSymbol(base, i, len);    /*  extract symbol     */
  232.         if (node = FindSymbol(base + b, i - b)) {
  233.             if (node->Type && SF_MACROARG && stringtize)
  234.             node->Type |= SF_STRINGIZE;
  235.             Dump(base, w, b);
  236.             w = i = HandleSymbol(node, base, i, len);
  237.             node->Type &= ~SF_STRINGIZE;
  238.         } else if (PreCompFlag) {
  239.             short t;
  240.  
  241.             /*
  242.              *    Precomp optimization
  243.              */
  244.  
  245.             if (t = PreCompSymbol(base + b, i - b)) {
  246.             Dump(base, w, b);
  247.             w = i;
  248.             putc(((char *)&t)[0], Fo);
  249.             putc(((char *)&t)[1], Fo);
  250.             }
  251.         }
  252.         stringtize = 0;
  253.         continue;
  254.         }                    /*    delete comments      */
  255.         if (stringtize)
  256.         cerror(EERROR_STRINGTIZE);
  257.  
  258.         if (SpecialChar[c]) {
  259.         if (c == '\'') {
  260.             i = SkipSingleSpec(base, i + 1, len);
  261.             continue;
  262.         }
  263.         if (c == '\"') {
  264.             i = SkipString(base, i + 1, len);
  265.             continue;
  266.         }
  267.         if (c == '/') {
  268.             if (base[i+1] == '*') {
  269.             Dump(base, w, i);
  270.             w = i = SkipComment(base, i + 2, len);
  271.             putc(' ', Fo);
  272.             continue;
  273.             }
  274.             if (base[i+1] == '/' && SlashSlashOpt) {
  275.             Dump(base, w, i);
  276.             w = i = SkipCommentLine(base, i + 2, len);
  277.             continue;
  278.             }
  279.         }
  280.         }
  281.         ++i;
  282.     }
  283.     Dump(base, w, i);
  284.     /* w = i */
  285.     }
  286.  
  287.     if (xbuf == NULL)
  288.     free(base);
  289.  
  290.     if (IfIndex != ifIndex)
  291.     cerror(EWARN_IFS_LEFT_PENDING, IfIndex, ifIndex);
  292.  
  293.     PushBase = inc.Next;
  294.  
  295.     if (PushBase) {
  296.     if (fi)
  297.         DoLineSpec();
  298.     return(PushBase->Index);
  299.     }
  300.     return(0);
  301. }
  302.  
  303. long
  304. SkipCommentLine(base, i, max)
  305. ubyte *base;
  306. long i;
  307. long max;
  308. {
  309.     while (i < max && base[i] != '\n')
  310.     ++i;
  311.     if (i == max)
  312.     cerror(EERROR_UNEXPECTED_EOF);
  313.     return(i);
  314. }
  315.  
  316. long
  317. SkipComment(base, i, max)
  318. ubyte *base;
  319. long i;
  320. long max;
  321. {
  322.     char c;
  323.  
  324.     while (i < max) {
  325.     c = base[i];
  326.     if (c == '/' && base[i+1] == '*')
  327.         cerror(EWARN_NESTED_COMMENT);
  328.     if (c == '*' && base[i+1] == '/')
  329.         break;
  330.     if (c == '\n') {
  331.         ++PushBase->LineNo;
  332.         putc('\n', Fo);
  333.     }
  334.     ++i;
  335.     }
  336.     if (i == max) {
  337.     cerror(EERROR_UNEXPECTED_EOF);
  338.     } else {
  339.     i += 2;
  340.     if (i > max)
  341.         cerror(EFATAL_SOFTERROR_177);
  342.     }
  343.     return(i);
  344. }
  345.  
  346. long
  347. ExtSymbol(base, i, max)
  348. ubyte *base;
  349. long i;
  350. long max;
  351. {
  352.     long b = i;
  353.     char *sc = SymbolChar;
  354.  
  355.     while (i < max && sc[base[i]])
  356.     ++i;
  357.  
  358.     dbprintf(("ExtSymbol: %.*s\n", i - b, base + b));
  359.  
  360.     return(i);
  361. }
  362.  
  363. #ifdef NOTDEF
  364.  
  365. /*
  366.  *  This routine strips comments from a buffer
  367.  */
  368.  
  369. void
  370. StripComments(buf, bytes)
  371. char *buf;
  372. long bytes;
  373. {
  374.     char c;
  375.     long i;
  376.     long b;
  377.  
  378.     for (i = 0; i < bytes; ++i) {
  379.     if (buf[i] == '/' && i + 1 < bytes) {
  380.         if (buf[i+1] == '*') {
  381.         b = i;
  382.         i += 2;
  383.         while (i < bytes) {
  384.             if (buf[i] == '*' && buf[i+1] == '/' && i + 1 < bytes) {
  385.             i += 2;
  386.             break;
  387.             }
  388.             ++i;
  389.         }
  390.         setmem(buf + b, i - b, ' ');
  391.         } else if (buf[i+1] == '/' && SlashSlashOpt) {
  392.         b = i;
  393.         while (i < bytes && buf[i] != '\n')
  394.             ++i;
  395.         setmem(buf + b, i - b, ' ');
  396.         --i;
  397.         }
  398.     }
  399.     }
  400. }
  401.  
  402. #endif
  403.  
  404. long
  405. SkipString(char *base, long i, long max)
  406. {
  407.     while (i < max && base[i] != '\"') {
  408.     /*
  409.      *  Embedded newline with no previous backslash
  410.      */
  411.  
  412.     if (base[i] == '\n') {
  413.         cerror(EERROR_UNTERMINATED_STRING);
  414.         break;
  415.     }
  416.  
  417.     /*
  418.      *  Leave backslashes alone.  The specical case of a \ followed
  419.      *  by a newline is handled by DC1
  420.      */
  421.  
  422.     if (base[i] == '\\') {
  423.         ++i;
  424.     }
  425.     ++i;
  426.     }
  427.     if (i < max)
  428.     ++i;
  429.     return(i);
  430. }
  431.  
  432. long
  433. SkipSingleSpec(char *base, long i, long max)
  434. {
  435.     while (i < max && base[i] != '\'') {
  436.     if (base[i] == '\n') {
  437.         cerror(EERROR_UNTERMINATED_CHARCONST);
  438.         break;
  439.     }
  440.     if (base[i] == '\\')
  441.         ++i;
  442.     ++i;
  443.     }
  444.     if (i < max)
  445.     ++i;
  446.     return(i);
  447. }
  448.  
  449. void
  450. Dump(base, w, i)
  451. char *base;
  452. long w;
  453. long i;
  454. {
  455.     if (w < i) {
  456.     if (IfEnabled) {
  457.         if (GlobalStringize) {
  458.         long n;
  459.         for (n = w; n < i; ++n) {
  460.             char c = base[n];
  461.             if (c < 32 || c == '\"' || c == '\'' /* || c == '\\'*/) {
  462.             fprintf(Fo, "\\%03o", (ubyte)c);
  463.             } else {
  464.             putc(c, Fo);
  465.             }
  466.         }
  467.         } else {
  468.         fwrite(base + w, 1, i - w, Fo);
  469.         }
  470.     } else {
  471.         while (w < i) {
  472.         if (base[w] == '\n')
  473.             fputc('\n', Fo);
  474.         ++w;
  475.         }
  476.     }
  477.     }
  478. }
  479.  
  480. void
  481. DoLineSpec()
  482. {
  483.     fprintf(Fo, "\n# %d \"%s\" %d\n", PushBase->LineNo, PushBase->FileName, PushBase->Level);
  484.     ForceLineSpec = 0;
  485. }
  486.  
  487.